﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Security.Cryptography;
using System.Data.SqlClient;
using System.Diagnostics;
using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace MSAS.DIP.Common
{
    public static class CommonExtensionMethods
    {
        #region Serialization Extension Methods
        /// <summary>
        /// Deserialize and cast result
        /// </summary>
        /// <typeparam name="T">Type of object to be deserialized</typeparam>
        /// <returns>Deserialized object</returns>
        /// <exception cref="System.InvalidOperationException"/>
        /// <exception cref="System.ArgumentNullException"/>
        public static T Deserialize<T>(string source)
        {
            T obj;
            using (StringReader reader = new StringReader(source))
            {
                obj = Deserialize<T>(reader);
            }
            return obj;
        }

        /// <summary>
        /// Deserialize and cast result
        /// </summary>
        /// <typeparam name="T">Type of object to be deserialized</typeparam>
        /// <returns>Deserialized object</returns>
        /// <exception cref="System.InvalidOperationException"/>
        public static T Deserialize<T>(TextReader reader)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(reader);
        }

        /// <summary>
        /// Serialize object to string
        /// </summary>
        /// <typeparam name="T">Type of object to be serialized</typeparam>
        /// <returns>String containing serialized object</returns>
        /// <exception cref="System.InvalidOperationException"/>
        public static string SerializeToString<T>(T objectToBeSerialized)
        {
            StringBuilder serializedObject = new StringBuilder();
            using (XmlWriter xmlWriter = XmlWriter.Create(serializedObject))
            {
                new XmlSerializer(objectToBeSerialized.GetType()).Serialize(xmlWriter, objectToBeSerialized);
            }
            return serializedObject.ToString();
        }

        #endregion

        #region Cryptography Extension Methods

        /// <summary>
        /// Compute the hash of a string
        /// </summary>
        /// <returns>Hexadecimal representation of hashed string</returns>
        /// <exception cref="System.ArgumentException"/>
        /// <exception cref="System.ArgumentNullException"/>
        /// <exception cref="System.ObjectDisposedException"/>
        /// <exception cref="System.Text.EncoderFallbackException"/>
        public static string ComputeHash(HashAlgorithm hashComputationObject, string stringToHash)
        {
            byte[] preHashedBytes = Encoding.Unicode.GetBytes(stringToHash);
            byte[] hashedBytes = hashComputationObject.ComputeHash(preHashedBytes);
            return BitConverter.ToString(hashedBytes).Replace("-", String.Empty);
        }

        #endregion

        #region Logging Extension Methods

        public static void LogConnectionToDatabase(string connectionString, int timeout)
        {
            LogEntry connectingToDatabase = new LogEntry()
            {
                Message = String.Format(
                    "Connecting to database: {0}Connection Timeout: {1}{0} Connection String: {2}",
                    Environment.NewLine,
                    timeout,
                    connectionString),
                EventId = (int)EventIdType.InformationConnectingToDatabase,
                Severity = TraceEventType.Information,
                Categories = { "SQL" }
            };
            Logger.Write(connectingToDatabase);
        }

        public static SqlConnection LogSqlConnection(string connectionString)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            LogConnectionToDatabase(connectionString, connection.ConnectionTimeout);
            return connection;
        }

        #endregion
    }
}
